iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Software Development

Python GUI 專案設計模式及好用的開發技巧系列 第 3

當Expection發生時, 如何顯示完整的CallStack和位置 (Traceback應用)

  • 分享至 

  • xImage
  •  

為了在python GUI 程式開發時有更好的開發者體驗, 筆者喜歡先收集別人的痛點及各種解決方案, 整理成屬於自己的優化方案再導入到GUI專案中, 而Exception 的呈現方式就是其中一個痛點.

引用自近期網友詢問Python 的Try Exception的問題片段 ...

引用來源: https://reurl.cc/XlWje3

在專案中有很多使用者會使用exception 去做例外的攔截, 但很常遇到的狀況是Exception並不會把完整的CallStack及位置顯示出來, 這就增添除錯時的困難度, 尤其在大型專案或多檔案的程式碼中, 不處理好就會演變成一場大災難.

來看個簡單的例子:

dict_a = {0:'hello',1:'hi'}
def run():
    try:
       print ("Hello, this is dmeo.\n")
       print(dict_a[2])
       print ("End")
    except Exception as err:
        print(err)
run()

例外發生的時候看不到完整的callstack 及行號

這次筆者使用traceback , 這個內建的模組做實驗

import sys
import traceback
 
dict_a = {0:'hello', 1:'hi'}

def run():
   try:
       print ("Hello, this is demo.\n")
       print (dict_a[2])
       print ("End")
   except Exception as err:
       err_type = err.__class__.__name__ # 取得錯誤的class 名稱
       info = err.args[0] # 取得詳細內容
       detains = traceback.format_exc() # 取得完整的tracestack
       n1, n2, n3 = sys.exc_info() #取得Call Stack
       lastCallStack =  traceback.extract_tb(n3)[-1] # 取得Call Stack 最近一筆的內容
       fn = lastCallStack [0] # 取得發生事件的檔名
       lineNum = lastCallStack[1] # 取得發生事件的行數
       funcName = lastCallStack[2] # 取得發生事件的函數名稱
       errMesg = f"FileName: {fn}, lineNum: {lineNum}, Fun: {funcName}, reason: {info}, trace:\n {traceback.format_exc()}"
       print(errMesg)
       
run()

流程

  1. 取得Exception的類型
  2. 取得最近一筆的的CallStack
  3. 利用traceback套件來解開Stack內容
  4. 取得檔名、行號、函數名稱
  5. 取得完整的callstack字串

執行結果

結論
我們可以把這個好用的模組使用方式包成一個簡單的模組, 搭配logging或寫成檔案去做相關的紀錄, 這樣就可以減少程式出錯後的除錯難度

參考資料


上一篇
好用的Python WYSIWYG GUI (PySide2)
下一篇
如何把痛點轉成未來的爽點 - 寫筆記的重要性
系列文
Python GUI 專案設計模式及好用的開發技巧31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言